package com.lz.ub.core

import com.lz.ub.*
import com.lz.ub.UBCOperator
import java.util.*

/**
 * @author You
 * 主板指令写, 多台设备多个指令
 */
internal class UBCWriter (private val operator: UBCOperator) : UBCWritable {

    //待连接的设备
    private val pendingDevices = LinkedList<UBCDevice>()

    //当前正在发数据的设备
    private var currentDevice: UBCDevice? = null

    //要写入的16进制数据
    private var hexCommand: String? = null

    //指令写出时的超时参数
    private var timeout = COMMAND_WRITE_TIMEOUT

    //推入要连接的设备, 推入前要判断状态[isAvailable]
    fun pushPendingDevices(devices: Collection<UBCDevice>, hexCommand: String, timeout: Int) {
        this.hexCommand = hexCommand
        this.timeout = timeout
        pendingDevices.addAll(devices)
        next(false)
    }

    fun pushPendingDevice(device: UBCDevice, hexCommand: String, timeout: Int) {
        this.hexCommand = hexCommand
        this.timeout = timeout
        pendingDevices.add(device)
        next(false)
    }

    private fun next(delayed: Boolean) {
        currentDevice = pendingDevices.pollFirst()
        if (currentDevice != null) {
            val device = currentDevice!!
            if (hexCommand != null) {
                if (delayed) Thread.sleep(COMMAND_WRITE_DELAYED)
                operator.write(device.writeCmd(hexCommand!!.length.shr(1), timeout), this)
            } else {
                next(delayed)
            }
        } else {
            operator.writeOver()
        }
    }

    fun writeCallback(size: Int) {
        if (currentDevice != null && hexCommand != null) {
            operator.writeHex(hexCommand!!)
        } else {
            next(true)
        }
    }

    override val label: String = "Write"

    override fun responseOk() {
        next(true)
    }

    override fun responseFail() {
        next(true)
    }

    override fun close() {
        pendingDevices.clear()
        currentDevice = null
    }

    override fun isAvailable(): Boolean = pendingDevices.isEmpty() && currentDevice == null
}